home *** CD-ROM | disk | FTP | other *** search
- Path: newshost.cyberramp.net!news
- From: sinan@cyberramp.net (John Noland)
- Newsgroups: comp.lang.misc,comp.lang.c,comp.lang.pl1
- Subject: Re: GOTO controversy
- Date: 12 Mar 1996 00:32:31 GMT
- Organization: Prose Software
- Message-ID: <4i2gmv$ect@newshost.cyberramp.net>
- References: <rcshlds.1.000A6705@mailserv.mta.ca> <Dn8pJ8.nqs@emi.net> <4grt4e$8fg@goanna.cs.rmit.EDU.AU> <4hl8mt$4po@newshost.cyberramp.net> <DnwCxp.84C@clw.cs.man.ac.uk>
- NNTP-Posting-Host: ramp1-12.cyberramp.net
- X-Newsreader: WinVN 0.99.5
-
- In article <DnwCxp.84C@clw.cs.man.ac.uk>, chl@clw.cs.man.ac.uk says...
- >
- >In <4hl8mt$4po@newshost.cyberramp.net> sinan@cyberramp.net (John Noland) writes:
- >
- >>>Robert C Shields (rcshlds@mailserv.mta.ca) wrote:
- >
- >>The above is NOT an example of a good use for the goto statement.
- >
- >Well that is what I thougut when I first saw the example, and I was about to
- >dash off an article like you have done. But then I looked again and saw
- >*exactly* what it was doing.
- >
- >So if you believe there is a better way, please can we see it?
- >
- I saw *exactly* what it was doing.
-
- I only have one problem with this example. It looks to me like he's trying to avoid
- duplicate code by using goto's. Yet, it seems to me that in the spot where he says:
-
- /* Do some stuff here */
- return TRUE; /* We did okay */
-
- really looks like this:
-
- /* Do some stuff here */
- NOTE>/* including this? */
- NOTE> free(ptr);
- NOTE> DosCloseMutexSem(hmtx);
- NOTE> DosCloseEventSem(hev3);
- NOTE> DosCloseEventSem(hev2);
- NOTE> DosCloseEventSem(hev1);
- return TRUE; /* We did okay */
-
- so the obvious change I would make is this:
-
- HEV hev1, hev2, hev3; /* Event semaphores */
- HMTX hmtx; /* Mutex semaphore */
- void *ptr;
- int retval; /* I'm assuming he's returning an int */
-
- /* There should be explicit initialization of all locals here */
-
- retval = TRUE;
-
- if (!DosCreateEventSem(0, &hev1, 0, FALSE))
- retval = FALSE;
- goto hev1_failed
-
- if (!DosCreateEventSem(0, &hev2, 0, FALSE))
- retval = FALSE;
- goto hev2_failed;
-
- if (!DosCreateEventSem(0, &hev3, 0, FALSE))
- retval = FALSE;
- goto hev3_failed;
-
- if (!DosCreateMutexSem(0, &hmtx, 0, FALSE))
- retval = FALSE;
- goto hmtx_failed;
-
- if ((ptr = malloc(SOME_SIZE)) == NULL)
- retval = FALSE;
- goto malloc_failed;
-
- /* Do some stuff here */
- free(ptr);
-
- malloc_failed:
- DosCloseMutexSem(hmtx);
- hmtx_failed:
- DosCloseEventSem(hev3);
- hev3_failed:
- DosCloseEventSem(hev2);
- hev2_failed:
- DosCloseEventSem(hev1);
- hev1_failed:
- return retval;
-
-
- To code a proper alternative to the goto's, I would really require some more
- information. I'm not familiar w/ this particular semaphore implementation,
- so I have to make some assumptions. I assume HEV and HMTX are structures
- that contain something similar to the UNIX implementation, semaphore value
- (semval), the process id of the last process to use the semphore(sempid),
- etc... In the implementations I've seen (and I'm not terribly knowledgeable
- about IPC mechanisms in general), there is a function called semget(). I don't
- know much about this, but I do know it returns a semaphore ID. I can't tell
- if that's what DosCreateXXXXSem() is doing or not. The original author treats
- it as a boolean. Something like the following would work to eliminate the goto's,
- but, it would be difficult to prove this method's superiority in this instance.
-
- typedef struct {
- int hev_return;
- HEV hev_struct;
- } HEV_SEM;
-
- typedef struct {
- int hmtx_return;
- HMTX hmtx_struct;
- } HMTX_SEM;
-
- int alloc_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
- void free_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
-
- int some_function(void) {
-
- int retval;
- HEV_SEM hev1, hev2, hev3; /* Event semaphores */
- HMTX_SEM hmtx; /* Mutex semaphore */
- void *ptr;
-
- retval = TRUE;
- memset((HEV_SEM *)&hev1, 0, sizeof (HEV_SEM));
- memset((HEV_SEM *)&hev2, 0, sizeof (HEV_SEM));
- memset((HEV_SEM *)&hev3, 0, sizeof (HEV_SEM));
- memset((HMTX_SEM *)&hmtx, 0, sizeof (HMTX_SEM));
-
- if (!alloc_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr)) {
- free_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr);
- return FALSE;
- }
- /* Do some stuff here */
- free_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr);
- return TRUE;
- }
-
- int alloc_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr) {
-
- if ((hev1->hev_return = DosCreateEventSem(0, &hev1->hev_struct, 0, FALSE)) == 0)
- return FALSE;
- if ((hev2->hev_return = DosCreateEventSem(0, &hev2->hev_struct, 0, FALSE)) == 0)
- return FALSE;
- if ((hev3->hev_return = DosCreateEventSem(0, &hev3->hev_struct, 0, FALSE)) == 0)
- return FALSE;
- if ((hmtx->hmtx_return = DosCreateMutexSem(0, &hmtx->hev_struct, 0, FALSE)) == 0)
- return FALSE;
- if ((ptr = malloc(SOME_SIZE)) == NULL)
- return FALSE;
- return TRUE;
- }
-
- void free_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
-
- if (ptr != NULL)
- free(ptr);
- if (hmtx->hmtx_return != 0)
- DosCloseMutexSem(hmtx->hmtx_struct);
- if (hev1->hev_return != 0)
- DosCloseEventSem(hev3->hev_struct);
- if (hev2->hev_return != 0)
- DosCloseEventSem(hev2->hev_struct);
- if (hev3->hev_return != 0)
- DosCloseEventSem(hev1->hev_struct);
-
- }
-
- If I made any mistakes here, I apologize. This code is off the top of my head.
-
- -John
-
-